/*
 * rtc_hal.c
 *
 *  Created on: Sep 18, 2013
 *      Author: Ken Arok
 */

#include "board.h"
#include "twi.h"
#include "rtc_hal.h"

#if RTC_PART_NAME_DS1307

/** \brief Write RTC data to DS1707 RTC Chip.
 *
 * \param _pbuf Pointer to RTC data to be written.
 *
 */
static void ds1307_write_datetime(void *_pbuf)
{
	twi_package_t rtc_datetime_t;

	/* Read Time and Date Register */
	rtc_datetime_t.addr[0] = VL_SECOND_ADDR;
	rtc_datetime_t.addr_length = sizeof(uint8_t);
	rtc_datetime_t.chip = TWI_RTC_SLAVE_ADDRESS;
	rtc_datetime_t.buffer = _pbuf;
	rtc_datetime_t.length = 7;

	if(_pbuf != NULL) {
		twi_master_write((const twi_package_t *)&rtc_datetime_t);
	}
}


/** \brief Read RTC data from DS1307 RTC Chip.
 *
 * \param _pbuf Pointer to buffer where RTC data will be copied.
 *
 */
static void ds1307_read_datetime(void *_pbuf) {
	twi_package_t rtc_clkout_t, rtc_datetime_t;
	uint8_t _rtc_enable_clkout[1] = {0x80};

	/* Enable CLKOUT */
	rtc_clkout_t.addr[0] = CLKOUT_CTRL_ADDR;
	rtc_clkout_t.addr_length = sizeof(uint8_t);
	rtc_clkout_t.chip = TWI_RTC_SLAVE_ADDRESS;
	rtc_clkout_t.buffer = _rtc_enable_clkout;
	rtc_clkout_t.length = 1;

	/* Read Time and Date Register */
	rtc_datetime_t.addr[0] = VL_SECOND_ADDR;
	rtc_datetime_t.addr_length = sizeof(uint8_t);
	rtc_datetime_t.chip = TWI_RTC_SLAVE_ADDRESS;
	rtc_datetime_t.buffer = _pbuf;
	rtc_datetime_t.length = 7;

	/* Enable CLKOUT */
	twi_master_write((const twi_package_t *)&rtc_clkout_t);

	/* Read time and date registers */
	twi_master_read((const twi_package_t *)&rtc_datetime_t);
}


/** \brief Read the CTRL status register of PCF8563.
 *
 * \return CTRL_VAL		Value of CTRL register.
 *
 */
static uint8_t ds1307_read_ctrl(void) {
	twi_package_t rtc_clkout_t, rtc_ctrl_t;
	uint8_t _rtc_enable_clkout[1] = {0x80};
	uint8_t _rtc_ctrl_status[1];

	/* Enable CLKOUT */
	rtc_clkout_t.addr[0] = CLKOUT_CTRL_ADDR;
	rtc_clkout_t.addr_length = sizeof(uint8_t);
	rtc_clkout_t.chip = TWI_RTC_SLAVE_ADDRESS;
	rtc_clkout_t.buffer = _rtc_enable_clkout;
	rtc_clkout_t.length = 1;

	/* Read Time and Date Register */
	rtc_ctrl_t.addr[0] = TIMER_CTRL_ADDR;
	rtc_ctrl_t.addr_length = sizeof(uint8_t);
	rtc_ctrl_t.chip = TWI_RTC_SLAVE_ADDRESS;
	rtc_ctrl_t.buffer = _rtc_ctrl_status;
	rtc_ctrl_t.length = 1;

	/* Enable CLKOUT */
	twi_master_write((const twi_package_t *)&rtc_clkout_t);

	/* Read time and date registers */
	twi_master_read((const twi_package_t *)&rtc_ctrl_t);


	return _rtc_ctrl_status[0];
}

#elif 0

#error Place another RTC chip definition here!

#endif /* RTC_PART_NAME_PCF8563 */

/* -------------------------------------------------------------------------------------- */

void rtc_write_calendar(rtc_raw_t *_rtc)
{
	uint8_t _pbuf[7];

#if RTC_PART_NAME_DS1307
	_pbuf[0] = _rtc->seconds & 0x7F;
	_pbuf[1] = _rtc->minutes & 0x7F;
	_pbuf[2] = _rtc->hours & 0x3F;
	_pbuf[3] = _rtc->weekdays & 0x07;
	_pbuf[4] = _rtc->days & 0x3F;
	_pbuf[5] = _rtc->months & 0x1F;
	_pbuf[6] = _rtc->years;
	ds1307_write_datetime(_pbuf);
#endif /*RTC_PART_NAME_DS1307 */
}


void rtc_read_calendar(rtc_raw_t *_rtc)
{
	uint8_t _pbuf[7];

#if RTC_PART_NAME_DS1307
	ds1307_read_datetime(_pbuf);
	/* Parse RTC raw. */
	_rtc->seconds = _pbuf[0] & 0x7F;
	_rtc->minutes = _pbuf[1] & 0x7F;
	_rtc->hours = _pbuf[2] & 0x3F;
	_rtc->weekdays = _pbuf[3] & 0x07;
	_rtc->days = _pbuf[4] & 0x3F;
	_rtc->months = _pbuf[5] & 0x1F;
	_rtc->years = _pbuf[6];
#endif /* RTC_PART_NAME_DS1307 */
}

uint8_t rtc_read_ctrl(void)
{
#if RTC_PART_NAME_DS1307
	return ds1307_read_ctrl();
#endif /* RTC_PART_NAME_DS1307 */

	return 0x00;
}
